#ifndef PROXY_CURL_CURl_CONN_H_
#define PROXY_CURL_CURl_CONN_H_

#include "proxy/base/proxybase.h"

namespace proxy{

  const char JSON_CHECK_UPDATE_VERSION_CODE[] = "version_code";
  const char JSON_CHECK_UPDATE_VERSION_KEY[] = "version_key";
  const char JSON_CHECK_UPDATE_FTP_URL[] = "ftp_url";

  class CurlClientSession : public boost::noncopyable,
    public boost::enable_shared_from_this<CurlClientSession>{
  public:
    enum SessionType{
      SESSION_TYPE_CLIENT,
      SESSION_TYPE_SERVER
    };
    typedef boost::shared_ptr<CurlClientSession> Ptr;
    //
    boost::signals2::signal < void(CurlClientSession::Ptr curl_session,
      int code) > SignalErrorMessage;
    boost::signals2::signal < void(CurlClientSession::Ptr curl_session) >
      SignalLoginSucceed;
    boost::signals2::signal < void(CurlClientSession::Ptr curl_session,
      std::string message) > SignalMessage;
    boost::signals2::signal <void(CurlClientSession::Ptr curl_session,
      std::string update_path_name) > SignalUpdateMessage;
    boost::signals2::signal < void(CurlClientSession::Ptr curl_session,
      std::string data) > SignalServerInfor;

    CurlClientSession(boost::asio::io_service &io_service, 
      SessionType session_type, int timeout, std::string &verion_key);
    virtual ~CurlClientSession();

    //
    void StartServerSession(std::string host, std::string url);
    void StartClientSession(std::string host, std::string url);
    void StartGetOnlineServerInfor(std::string host, std::string url);
    bool StartFtpDownload(std::string ftp_url, 
      std::string authen, std::string save_path);
    bool StartCheckUpdateAndDownload(std::string ftp_url,
      std::string authen, std::string save_path, std::string version_name);

    void Stop(){ is_connect_ = false; };
    void AddFlow(int flow){ flow_ = flow_ + flow; }
    bool IsConnect() const { return is_connect_; }
  private:
    void HandleThreadServerSession(std::string host, std::string url);
    void HandleThreadClientSession(std::string host, std::string url);
    void HandleThreadGetServerInfor(std::string host, std::string url);
    void HandleThreadCheckUpdateAndDownload(std::string check_url,
      std::string authen, std::string save_path, std::string version_name);
    std::string ProcessUrl(std::string url);
    void LoopPing(std::string url);
    int VerifyPingMessage(std::string &msg);
    bool FtpDownload(std::string &ftp_url, std::string &authen, 
      std::string &path_name, std::string &ver_key);
    std::string IntegerToString(int n);
    bool GeneratorFileKey(const char *path_name, std::string &ver_key);
    bool Md5Compare(unsigned char *digest, std::string &key);
    
  public:
    volatile int flow_;
  private:
    static const int CONST_KEY_SIZE = 16;
    static const int CONST_STRING_KEY_SIZE = 32;
    boost::asio::io_service &io_service_;
    std::string result_;
    SessionType session_type_;
    int timeout_;
    bool is_connect_;
    bool is_update_checking_;

    // update key
    std::string verion_key_;
    std::string save_path_;
  };
}


#endif // PROXY_CURL_CURl_CONN_H_